/**
  ******************************************************************************
  * @file    rtc.c
  * @brief   This file provides code for the configuration
  *          of the RTC instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "rtc.h"

/* USER CODE BEGIN 0 */
#include "Printf_Use.h"
RTC_DateTypeDef GetData;  //获取日期结构�?
RTC_TimeTypeDef GetTime;   //获取时间结构�?
/* USER CODE END 0 */

RTC_HandleTypeDef hrtc;

/* RTC init function */
void MX_RTC_Init(void)
{

  /* USER CODE BEGIN RTC_Init 0 */

  /* USER CODE END RTC_Init 0 */

  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef DateToUpdate = {0};
  RTC_AlarmTypeDef sAlarm = {0};

  /* USER CODE BEGIN RTC_Init 1 */

  /* USER CODE END RTC_Init 1 */
  /** Initialize RTC Only
  */
  hrtc.Instance = RTC;
  hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
  hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */

  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date
  */
  sTime.Hours = 0x15;
  sTime.Minutes = 0x42;
  sTime.Seconds = 0x30;

  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY;
  DateToUpdate.Month = RTC_MONTH_JULY;
  DateToUpdate.Date = 0x24;
  DateToUpdate.Year = 0x23;

  if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /** Enable the Alarm A
  */
  sAlarm.AlarmTime.Hours = 0x0;
  sAlarm.AlarmTime.Minutes = 0x1;
  sAlarm.AlarmTime.Seconds = 0x0;
  sAlarm.Alarm = RTC_ALARM_A;
  if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */
    // 启动闹钟中断事件
    HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
  /* USER CODE END RTC_Init 2 */

}

void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{

  if(rtcHandle->Instance==RTC)
  {
  /* USER CODE BEGIN RTC_MspInit 0 */

  /* USER CODE END RTC_MspInit 0 */
    HAL_PWR_EnableBkUpAccess();
    /* Enable BKP CLK enable for backup registers */
    __HAL_RCC_BKP_CLK_ENABLE();
    /* RTC clock enable */
    __HAL_RCC_RTC_ENABLE();

    /* RTC interrupt Init */
    HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
  /* USER CODE BEGIN RTC_MspInit 1 */

  /* USER CODE END RTC_MspInit 1 */
  }
}

void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
{

  if(rtcHandle->Instance==RTC)
  {
  /* USER CODE BEGIN RTC_MspDeInit 0 */

  /* USER CODE END RTC_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_RTC_DISABLE();

    /* RTC interrupt Deinit */
    HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn);
  /* USER CODE BEGIN RTC_MspDeInit 1 */

  /* USER CODE END RTC_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */
//----------------------------------------------------------
//获取RTC时间日期
void RTC_GETTIME(void)
{
    /* Get the RTC current Time */
    HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
    /* Get the RTC current Date */
    HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);

    /* Display date Format : yy/mm/dd */
    printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
    /* Display time Format : hh:mm:ss */
    printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);

    printf("\r\n");
}
//stop模式
void sys_enter_stop_mode(void)
{
    __HAL_RCC_PWR_CLK_ENABLE();                                                // 使能PWR时钟
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);                                         // 清除唤醒标记
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);        // 进入STOP模式
}
//standby模式
void sys_enter_standby_mode(void)
{
    __HAL_RCC_PWR_CLK_ENABLE();           // 使能PWR时钟
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);    // 清除唤醒标记
    HAL_PWR_EnterSTANDBYMode();           // 进入待机模式
}
//sleep模式
void sys_enter_sleep_mode(void)
{
    __HAL_RCC_PWR_CLK_ENABLE();           // 使能PWR时钟
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);    // 清除唤醒标记
    HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON,PWR_SLEEPENTRY_WFE);       // 进入睡眠模式
}
//获取当前时间
void RTC_GetTime(rtc_time_t* time)
{
    HAL_RTC_GetTime(&hrtc, (RTC_TimeTypeDef *)&time->Hours,   RTC_FORMAT_BIN);
    HAL_RTC_GetDate(&hrtc, (RTC_DateTypeDef *)&time->WeekDay, RTC_FORMAT_BIN);
}
//设置当前时间
void RTC_SetTime(rtc_time_t* time)
{
    HAL_RTC_SetTime(&hrtc, (RTC_TimeTypeDef *)&time->Hours,   RTC_FORMAT_BIN);
    HAL_RTC_SetDate(&hrtc, (RTC_DateTypeDef *)&time->WeekDay, RTC_FORMAT_BIN);
}
//设置唤醒时间
void RTC_AlarmStart(void)
{
    RTC_AlarmTypeDef sAlarm = {0};
    rtc_time_t tim = {0};

    // 获取当前时间
    RTC_GetTime(&tim);

    sAlarm.AlarmTime.Hours = tim.Hours;
    sAlarm.AlarmTime.Minutes = tim.Minutes + 1; //当前时间的1分钟后唤醒
    sAlarm.AlarmTime.Seconds = tim.Seconds;
    sAlarm.Alarm = RTC_ALARM_A;

    // 启动闹钟中断事件
    HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
}
//唤醒中断回调函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
    SystemClock_Config();  // STOP模式唤醒后默认时钟主频为内部8M时钟，所以要先初始化时钟配置
    printf("1分钟时间到，唤醒！\r\n");
}

//设置一分钟后唤醒，并随即进入standby模式
void standby_1M(void)
{
    // 配置下次唤醒的闹钟时钟
    RTC_AlarmStart();
    // 进入待机模式，待机模式唤醒后相当于复位，程序从头开始运行
    sys_enter_standby_mode();
}
//设置一分钟后唤醒，并随即进入stop模式
void stop_1M(void)
{
    // 配置下次唤醒的闹钟时钟
    RTC_AlarmStart();
    // 进入STOP模式，程序停止在此处等待唤醒后往下执行
    sys_enter_stop_mode();
}
//设置一分钟后唤醒，并随即进入sleep模式
void sleep_1M(void)
{
    // 配置下次唤醒的闹钟时钟
    RTC_AlarmStart();
    // 进入SLEEP模式，只有内核时钟关闭并且停止运行，外设都还在运行
    sys_enter_sleep_mode();
}
//----------------------------------------------------------
/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
